package org.example.diary.controller;

import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.example.diary.entity.dto.LoginUser;
import org.example.diary.entity.dto.SysUserAddDTO;
import org.example.diary.entity.dto.SysUserDTO;
import org.example.diary.entity.dto.SysUserListDTO;
import org.example.diary.entity.vo.Response;
import org.example.diary.entity.vo.UserListVO;
import org.example.diary.entity.vo.UserVO;
import org.example.diary.service.UserService;
import org.example.diary.validator.SaveGroup;
import org.example.diary.validator.UpdateGroup;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import static org.example.diary.constant.Constant.TOKEN_MAP;

@Slf4j
@Validated
@RestController
public class UserController {

    @Resource
    private UserService userService;
    @PostMapping("user_login")
    public Response<UserVO> login(@RequestBody @Valid SysUserDTO sysUserDTO){
        return Response.ok(userService.login(sysUserDTO));
    }

    @PreAuthorize("isAuthenticated()")
    @PostMapping("user_logout")
    public Response<String> logout(HttpServletRequest request, HttpServletResponse response){
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null){
            LoginUser loginUser = (LoginUser) auth.getPrincipal();
            Long id = loginUser.getSysUser().getId();
            TOKEN_MAP.remove(id);
            new SecurityContextLogoutHandler().logout(request, response, auth);
            // 2. 手动清除SecurityContext
            SecurityContextHolder.clearContext();
            // 3. 使Session失效（双重保障）
            HttpSession session = request.getSession(false);
            if (session != null) {
                session.invalidate();
            }
        }
        return null;
    }

    @PreAuthorize("hasRole('admin')")
    @GetMapping("user_list")
    public Response<PageInfo<UserListVO>> userList(SysUserListDTO sysUserAddDTO){
        return Response.ok(userService.userList(sysUserAddDTO));
    }

    @PreAuthorize("hasRole('admin')")
    @PostMapping("user_add")
    public Response<String> userAdd(@RequestBody @Validated({SaveGroup.class}) SysUserAddDTO sysUserAddDTO){
         return Response.ok(userService.userAdd(sysUserAddDTO));
    }

    @PreAuthorize("hasRole('admin')")
    @PostMapping("user_update")
    public Response<String> userUpdate(@RequestBody @Validated({UpdateGroup.class}) SysUserAddDTO sysUserAddDTO){
        return Response.ok(userService.userUpdate(sysUserAddDTO));
    }
    @PreAuthorize("hasRole('admin')")
    @PostMapping("user_del/{userId}")
    public Response<String> userDel(@PathVariable Integer userId){
        return Response.ok(userService.userIdDel(userId));
    }

    @PreAuthorize("hasRole('admin')")
    @PostMapping("user_disable")
    public Response<String> userDisable(@Valid @NotNull(message = "id不能为空") @RequestParam Integer id,
                                        @Valid @NotNull(message = "status不能为空") @RequestParam Integer status){
        return Response.ok(userService.userDisable(id,status));
    }

}
